Debugging software programs can be particularly difficult for multithreaded programs. For example, accesses to shared resources, such as memory locations, are not often properly shielded from code bugs. In particular, threads can attempt to concurrently access the same shared resources which result in invalid internal states which can, in turn, result in program crashes and/or invalid results.